package co.com.smart.eagle.client;

import co.com.smart.eagle.client.view.impl.components.SmartAlertDialog.CallBackModal;
import co.com.smart.eagle.client.view.util.SmartLoading;
import co.com.smart.eagle.client.view.util.SmartMensajes;
import co.com.smart.eagle.infrastructure.dto.SmartExcepcionSerializada;
import co.com.smart.eagle.infrastructure.dto.SmartTipoMensajes;

import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.InvocationException;
import com.google.gwt.user.client.rpc.StatusCodeException;

public abstract class EagleCallBack<T> implements
		AsyncCallback<ParametroHandler<T>> {

	private boolean mostrarMensaje = false;

	public interface CallBackError {
		void callBack();
	}

	private CallBackError callBackError;

	public EagleCallBack(boolean ocultarMensaje, CallBackError callBack) {
		this(ocultarMensaje);
		callBackError = callBack;
	}

	public EagleCallBack(CallBackError callBack) {
		callBackError = callBack;
	}

	public EagleCallBack(boolean ocultarMensaje) {
		mostrarMensaje = ocultarMensaje;
	}

	public EagleCallBack() {
	}

	@Override
	public void onFailure(Throwable th) {
		if (th instanceof InvocationException
				&& !(th instanceof StatusCodeException)
				&& (((InvocationException) th).getMessage().contains("login"))) {
			SmartMensajes.getInstance().show("Error carga inicial",
					th.getMessage(), SmartTipoMensajes.ERROR,
					new CallBackModal() {

						@Override
						public void finModal() {
							Window.Location.reload();
						}
					});
		} else {
			if (callBackError != null) {
				callBackError.callBack();
			}
			SmartMensajes.getInstance().show("Error carga inicial",
					th.getMessage(), SmartTipoMensajes.ERROR,
					new CallBackModal() {

						@Override
						public void finModal() {
							Window.Location.reload();
						}
					});

			th.printStackTrace();
		}
	}

	@Override
	public void onSuccess(ParametroHandler<T> response) {
		if (response != null) {
			if (response.getSmartExcepcionSerializada() != null) {
				try {
					procesarExcepcion(response.getSmartExcepcionSerializada());
				} catch (Exception e) {
					SmartMensajes
							.getInstance()
							.show("Error de comunicaci\u00F3n",
									"Excepci\u00F3n imposible de recuperar\npor favor intente nuevamente");
				}
				if (callBackError != null) {
					callBackError.callBack();
				}
			} else {
				try {
					success(response.getParametroRetorno());
				} catch (Throwable e) {
					SmartMensajes.getInstance().show(
							"Error de comunicaci\u00F3n", e.getMessage());
				} finally {
					if (mostrarMensaje) {
						SmartLoading.getInstance().hide();
					}
				}
			}

		} else {
			if (callBackError != null) {
				callBackError.callBack();
			}
		}
	}

	private void procesarExcepcion(
			SmartExcepcionSerializada excepcionSerializada) {
		SmartMensajes.getInstance().show("Error de procesamiento",
				excepcionSerializada.getMensaje(), SmartTipoMensajes.ERROR,
				new CallBackModal() {

					@Override
					public void finModal() {
						if (mostrarMensaje) {
							SmartLoading.getInstance().hide();
						}
					}
				});
	}

	public abstract void success(T result);

}
